package com.jeeplus.modules.api.utils;

import com.jeeplus.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Tool {
	
	private static final Logger logger = LoggerFactory.getLogger(Tool.class);
	
	/**
	 * MD5
	 * @param inStr
	 * @return
	 */
	public static String MD5(String inStr)
	{
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			System.out.println(e.toString());
			e.printStackTrace();
			return "";
		}
		byte[] byteArray = null;
		try {
			byteArray = inStr.getBytes("gbk");
		} catch (UnsupportedEncodingException e) {
			return null;
		}
		byte[] md5Bytes = md5.digest(byteArray);
		StringBuilder hexValue = new StringBuilder();
		for (byte md5Byte : md5Bytes) {
			int val = md5Byte & 0xFF;
			if (val < 16)
				hexValue.append("0");
			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();
	}
	/**
	 * 检查是否是邮箱
	 * @param email
	 * @return
	 */
	public static boolean checkEmail(String email){
		 Pattern pattern = Pattern.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");
		 Matcher matcher = pattern.matcher(email);
		 return matcher.matches();
	}
	/** 
     * 手机号验证 
     *  
     * @param  str 
     * @return 验证通过返回true 
     */  
    public static boolean isMobile(String str) {   
        Pattern p = null;  
        Matcher m = null;  
        boolean b = false;   
        p = Pattern.compile("^[1][1,2,3,4,5,6,8,7,9][0-9]{9}$"); // 验证手机号  
        m = p.matcher(str);  
        b = m.matches();   
        return b;  
    }  
	/** 
     * 用户号验证 
     *  
     * @param  str 
     * @return 验证通过返回true 
     */  
    public static boolean isuserNum(String str) {   
        Pattern p = null;  
        Matcher m = null;  
        boolean b = false;   
        p = Pattern.compile("^[0-9]{3,5}$"); // 验证用户号 
        m = p.matcher(str);  
        b = m.matches();   
        return b;  
    }   
   /**
    * 根据经纬度计算距离,计算结果为米
    * @return
    */
    public static String GetDistance(double lng1, double lat1, double lng2, double lat2){
    	String str="";
    	try {
	    	double EARTH_RADIUS = 6378137;
		    double radLat1 = rad(lat1);
		    double radLat2 = rad(lat2);
		    double a = radLat1 - radLat2;
		    double b = rad(lng1) - rad(lng2);
		    double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) + 
		    Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
		    s = s * EARTH_RADIUS;
		    s = Math.round(s * 10000) / 10000;
		   
		    if(s>1000){
		    	DecimalFormat df = new DecimalFormat("0.0");
		    	str= df.format(s/1000)+"km";
		    }else{
		    	str=s+"m";
		    }
    	} catch (Exception e) {
    		logger.error("处理异常{}",e);
		}
	    return str;
     }
    private static double rad(double d){
    	 return d * Math.PI / 180.0;
    }
    
    /**
     * 根据经纬度计算距离,计算结果为米
     * @return
     */
     public static double GetDistance1(double lng1, double lat1, double lng2, double lat2){
    	 double s=0.00;
    	 try {
 	    	double EARTH_RADIUS = 6378137;
 		    double radLat1 = rad(lat1);
 		    double radLat2 = rad(lat2);
 		    double a = radLat1 - radLat2;
 		    double b = rad(lng1) - rad(lng2);
 		    s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) + 
 		    Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
 		    s = s * EARTH_RADIUS;
 		    s = Math.round(s * 10000) / 10000;
     	} catch (Exception e) {
     		logger.error("处理异常{}",e);
 		}
 	    return s;
      }
	public static void main(String[] args) {
		System.out.println((int)GetDistance1(106.503985,29.612454,106.60632,29.665191));
    } 	
	
	/**
	 * 判断多个参数中有没有为空的
	 * @param strs
	 * @return
	 */
	public static boolean isNotEmptyBatch(String... strs){
		
		for (String str : strs) {
			if(StringUtils.isEmpty(str))
				return false;
		}
		return true;
	}
	/*public static void main(String[] args) throws ParseException {
		Boolean b = Tool.isNotEmptyBatch("1","2","3");
		System.out.println(b);
		//System.out.println(generate());
		//System.out.println(hongbaoMoney(100, 99));
//		System.out.println(getAgeByBirth(new SimpleDateFormat("yyyy-MM-dd").parse("1992-04-06")));
		String str="鸭是为餐桌上的上乘肴馔，也是人们进补的优良食品。鸭肉的营养价值与鸡肉相仿。但在中医看来，鸭子吃的食物多为水生物，故其肉性味甘、寒，入肺胃肾经，有滋补、养胃、补肾、除痨热骨蒸、消水肿、止热痢、止咳化痰等作用。凡体内有热的人适宜食鸭肉，体质虚弱，食欲不振，发热，大便干燥和水肿的人食之更为有益。民间还传说，鸭是肺结核病人的\"圣药\"";
		System.out.println(str);
		System.out.println(addDateMinut(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), 2));
	}*/
	
	//根据日期判断是否周六
	public static boolean isWeekend(Date date) throws ParseException{
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		if(cal.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY){
			return true;
		}
		else return false;
	}
	
	/**
	 * java生成一个由大写字母和数字组成的6位的随机字符串(想要不重复的将注释的放开)
	 * @return
	 */
	public static String generate() {
	    char[] letters = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
	            'K', 'L', 'M', 'N', 'O', 'P','Q', 'R', 'S', 'T', 'U', 'V',
	            'W', 'X', 'Y', 'Z','0','1','2','3','4','5','6','7','8','9'};
	    boolean[] flags = new boolean[letters.length];
	    char[] chs = new char[6];
	    for (int i = 0; i < chs.length; i++) {
	        int index;
	        index = (int) (Math.random() * (letters.length));
	       /* do {
	            index = (int) (Math.random() * (letters.length));
	        } while (flags[index]);// 判断生成的字符是否重复*/
	        chs[i] = letters[index];
	        flags[index] = true;
	    }
	    return new String(chs);
	}
	
	//返回图片视频链接
	public static String getImageUrl(String str){
		if(StringUtils.isNotEmpty(str) && !str.contains("http://") && !str.contains("https://")){
			//str = Global.getConfig("filePath")+str;
			str = "http://192.168.2.2:8080/"+str;
		}
		return str;
	}
	
	//米转换千米
	public static String todistance(String s) {
		if(s.contains(".")){
			s=s.substring(0, s.indexOf("."));
		}
		try {
			float a=Float.parseFloat(s);
			if(a>=1000){
				 a=(float)(Math.round(a/100))/10;
				 s=a+"km";
			}else{
				s=s+"m";
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
		return s;
	}
	
	/** 
	 * 对List对象按照某个成员变量进行排序 
	 * @param list       List对象 
	 * @param sortField  排序的属性名称 
	 * @param sortMode   排序方式：ASC，DESC 任选其一 
	 */  
	public static <T> void sortList(List<T> list, final String sortField, final String sortMode) {
		if (list == null || list.size() < 2) {
			return;
		}
		list.sort(new Comparator<T>() {
			@Override
			public int compare(T o1, T o2) {
				try {
					Class clazz = o1.getClass();
					Field field = clazz.getDeclaredField(sortField); // 获取成员变量
					field.setAccessible(true); // 设置成可访问状态
					String typeName = field.getType().getName().toLowerCase(); // 转换成小写

					Object v1 = field.get(o1); // 获取field的值
					Object v2 = field.get(o2); // 获取field的值

					boolean ASC_order = (sortMode == null || "ASC".equalsIgnoreCase(sortMode));

					// 判断字段数据类型，并比较大小
					if (typeName.endsWith("string")) {
						String value1 = v1.toString();
						String value2 = v2.toString();
						return ASC_order ? value1.compareTo(value2) : value2.compareTo(value1);
					} else if (typeName.endsWith("short")) {
						Short value1 = Short.parseShort(v1.toString());
						Short value2 = Short.parseShort(v2.toString());
						return ASC_order ? value1.compareTo(value2) : value2.compareTo(value1);
					} else if (typeName.endsWith("byte")) {
						Byte value1 = Byte.parseByte(v1.toString());
						Byte value2 = Byte.parseByte(v2.toString());
						return ASC_order ? value1.compareTo(value2) : value2.compareTo(value1);
					} else if (typeName.endsWith("char")) {
						Integer value1 = (int) (v1.toString().charAt(0));
						Integer value2 = (int) (v2.toString().charAt(0));
						return ASC_order ? value1.compareTo(value2) : value2.compareTo(value1);
					} else if (typeName.endsWith("int") || typeName.endsWith("integer")) {
						Integer value1 = Integer.parseInt(v1.toString());
						Integer value2 = Integer.parseInt(v2.toString());
						return ASC_order ? value1.compareTo(value2) : value2.compareTo(value1);
					} else if (typeName.endsWith("long")) {
						Long value1 = Long.parseLong(v1.toString());
						Long value2 = Long.parseLong(v2.toString());
						return ASC_order ? value1.compareTo(value2) : value2.compareTo(value1);
					} else if (typeName.endsWith("float")) {
						Float value1 = Float.parseFloat(v1.toString());
						Float value2 = Float.parseFloat(v2.toString());
						return ASC_order ? value1.compareTo(value2) : value2.compareTo(value1);
					} else if (typeName.endsWith("double")) {
						Double value1 = Double.parseDouble(v1.toString());
						Double value2 = Double.parseDouble(v2.toString());
						return ASC_order ? value1.compareTo(value2) : value2.compareTo(value1);
					} else if (typeName.endsWith("boolean")) {
						Boolean value1 = Boolean.parseBoolean(v1.toString());
						Boolean value2 = Boolean.parseBoolean(v2.toString());
						return ASC_order ? value1.compareTo(value2) : value2.compareTo(value1);
					} else if (typeName.endsWith("date")) {
						Date value1 = (Date) (v1);
						Date value2 = (Date) (v2);
						return ASC_order ? value1.compareTo(value2) : value2.compareTo(value1);
					} else if (typeName.endsWith("timestamp")) {
						Timestamp value1 = (Timestamp) (v1);
						Timestamp value2 = (Timestamp) (v2);
						return ASC_order ? value1.compareTo(value2) : value2.compareTo(value1);
					} else {
						// 调用对象的compareTo()方法比较大小
						Method method = field.getType().getDeclaredMethod("compareTo", field.getType());
						method.setAccessible(true); // 设置可访问权限
						int result = (Integer) method.invoke(v1, new Object[]{v2});
						return ASC_order ? result : result * (-1);
					}
				} catch (Exception e) {
					String err = e.getLocalizedMessage();
					System.out.println(err);
					e.printStackTrace();
				}
				return 0; // 未知类型，无法比较大小
			}
		});
	}
	
	/**
     * 将数组转换成以逗号分隔的字符串
     * 
     * @param needChange
     *            需要转换的数组
     * @return 以逗号分割的字符串
     */
    public static String arrayToStrWithComma(String[] needChange) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < needChange.length; i++) {
            sb.append(needChange[i]);
            if ((i + 1) != needChange.length) {
                sb.append("|");
            }
        }
        return sb.toString();
    }
    
    /**
	 * 指定日期加上天数后的日期
	 * 
	 * @param num
	 *            为增加的天数
	 * @param newDate
	 *            创建时间
	 * @return
	 * @throws ParseException
	 */
	public static String plusDay(int num, String newDate) throws ParseException {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date currdate = format.parse(newDate);
		System.out.println("现在的日期是：" + currdate);
		Calendar ca = Calendar.getInstance();
		ca.add(Calendar.DATE, num);// num为增加的天数，可以改变的
		currdate = ca.getTime();
		String enddate = format.format(currdate);
		System.out.println("增加天数以后的日期：" + enddate);
		return enddate;
	}
    
    /**
	 * 当前日期加上天数后的日期
	 * 
	 * @param num
	 *            为增加的天数
	 * @return
	 */
	public static String plusDay2(int num) {
		Date d = new Date();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String currdate = format.format(d);
		System.out.println("现在的日期是：" + currdate);

		Calendar ca = Calendar.getInstance();
		ca.add(Calendar.DATE, num);// num为增加的天数，可以改变的
		d = ca.getTime();
		String enddate = format.format(d);
		System.out.println("增加天数以后的日期：" + enddate);
		return enddate;
	}
	
	/**
	 * 指定日期加上月数后的日期
	 * 
	 * @param month
	 *            为增加的月数
	 * @return
	 */
	public static String addMonth(String date,int month){
	    String nowDate = null;
	    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	    try {
	        Date parse = format.parse(date);
	        Calendar calendar = Calendar.getInstance();
	        calendar.setTime(parse);
	        calendar.add(Calendar.MONTH, month);
	        nowDate = format.format(calendar.getTime());
	    } catch (ParseException e) {
	        e.printStackTrace();
	    }
	    return nowDate;
	}
	
	/**
	 * java求指定范围和小数位的随机数
	 * @param max 最大值
	 * @param min 最小值
	 * @return
	 */
	public static String hongbaoMoney(double max,double min) {
		BigDecimal db = new BigDecimal(Math.random() * (max - min) + min);
		String randomNum=db.setScale(2, BigDecimal.ROUND_HALF_UP).toString();//保留2位小数并四舍五入  
        System.out.println(randomNum);  
		return randomNum;
	}
	
	/**
	 * 判断是否超过4小时
	 * 
	 * @param date1
	 * @param date2
	 * @return boolean
	 * @throws Exception
	 */
	public static boolean judgmentDate(String date1, String date2) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date start = sdf.parse(date1);
		Date end = sdf.parse(date2);
		long cha = end.getTime() - start.getTime();
		if (cha < 0) {
			return false;
		}
		double result = cha * 1.0 / (1000 * 60 * 60);
		if (result >= 4) {
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * java根据出生日期自动计算年龄
	 * @param birthDay
	 * @return
	 * @throws ParseException
	 */
	public static int getAgeByBirth(Date birthDay) throws ParseException {
		int age = 0;
		Calendar cal = Calendar.getInstance();
		if (cal.before(birthDay)) { // 出生日期晚于当前时间，无法计算
			throw new IllegalArgumentException("The birthDay is before Now.It's unbelievable!");
		}
		int yearNow = cal.get(Calendar.YEAR); // 当前年份
		int monthNow = cal.get(Calendar.MONTH); // 当前月份
		int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH); // 当前日期
		cal.setTime(birthDay);
		int yearBirth = cal.get(Calendar.YEAR);
		int monthBirth = cal.get(Calendar.MONTH);
		int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
		age = yearNow - yearBirth; // 计算整岁数
		if (monthNow <= monthBirth) {
			if (monthNow == monthBirth) {
				if (dayOfMonthNow < dayOfMonthBirth)
					age--;// 当前日期在生日之前，年龄减一
			} else {
				age--;// 当前月份在生日之前，年龄减一
			}
		}
		return age;
	} 
	
	/**
     * 给时间加上几个小时
     * @param day 当前时间 格式：yyyy-MM-dd HH:mm:ss
     * @param hour 需要加的时间
     * @return
     */
    public static String addDateMinut(String day, int hour){   
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	Date date = null;   
    	try {   
    		date = format.parse(day);   
    	} catch (Exception ex) {   
    		ex.printStackTrace();   
    	}   
    	if (date == null)   
    		return "";   
    	System.out.println("front:" + format.format(date)); //显示输入的日期  
    	Calendar cal = Calendar.getInstance();   
    	cal.setTime(date);   
    	cal.add(Calendar.HOUR, hour);// 24小时制   
    	date = cal.getTime();   
    	System.out.println("after:" + format.format(date));  //显示更新后的日期 
    	cal = null;   
    	return format.format(date);   
    	
    }
    
    /**
     * 获取随机的流水号(10位)
     * @return
     */
	public static String getRandomReqNo(int length) {
		String base = "0123456789";
		Random random = new Random();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	} 
}
